package manager

import (
	"context"
	"quant/backend/constants"
	"quant/backend/entity"
	"quant/backend/qmt"

	"github.com/duke-git/lancet/v2/slice"
)

type StockManager struct {
	// 引入公共类
	// BaseManager
	*BaseManager[entity.StockEntity]
}

func NewStockManager() *StockManager {
	return &StockManager{
		BaseManager: newManager[entity.StockEntity](),
	}
}

func (sm *StockManager) SwitchStatus(id int64) (int64, error) {
	stock, err := sm.GetByID(id)
	if err != nil {
		return 0, err
	}
	stock.Enabled = !stock.Enabled
	return sm.Update([]string{"enabled"}, id, stock)
}

func (sm *StockManager) UpdateStockList() (int64, int64, error) {
	// 从MINIQMT获取所有股票代码
	codeList, err := qmt.GetStockCodeListBySector(constants.SectorName)
	if err != nil {
		return 0, 0, err
	}
	// 所有股票列表
	stockList, err := sm.FindAll()
	if err != nil {
		return 0, 0, err
	}
	// 把股票列表转换成 map，key 为股票代码，value 为股票对象
	mapStock := make(map[string]entity.StockEntity)
	for _, stock := range stockList {
		mapStock[stock.Code] = stock
	}
	existCodeList := slice.Map(stockList, func(index int, item entity.StockEntity) string {
		return item.Code
	})

	newCodeList := slice.Filter(codeList, func(index int, code string) bool {
		return !slice.Contain(existCodeList, code)
	})
	// 使用事务批量插入
	totalCreated, err := sm.WithTx(context.Background(), func(mgr *BaseManager[entity.StockEntity]) (int64, error) {
		var count int64
		for _, code := range newCodeList {
			detail, er := qmt.GetInstrumentDetail(code)
			if er != nil {
				return 0, er
			}

			stock := entity.StockEntity{
				Code:        code,
				Name:        detail.InstrumentName,
				Enabled:     true,
				FloatVolume: detail.FloatVolume,
				TotalVolume: detail.TotalVolume,
			}
			_, er = sm.Create(&stock)
			if er != nil {
				return 0, er
			} else {
				count++
			}

		}
		return count, nil
	})
	if err != nil {
		return 0, 0, err
	}

	// 使用事务批量修改
	totalUpdated, err := sm.WithTx(context.Background(), func(mgr *BaseManager[entity.StockEntity]) (int64, error) {
		var count int64
		for _, code := range existCodeList {
			detail, er := qmt.GetInstrumentDetail(code)
			if er != nil {
				return 0, er
			}

			stock := mapStock[code]
			stock.Code = code
			stock.Name = detail.InstrumentName
			stock.Enabled = true
			stock.FloatVolume = detail.FloatVolume
			stock.TotalVolume = detail.TotalVolume
			_, er = sm.Update(nil, stock.Id, &stock)
			if er != nil {
				return 0, er
			} else {
				count++
			}
		}
		return count, nil
	})
	if err != nil {
		return 0, 0, err
	}

	return totalCreated, totalUpdated, nil
}

// func (sm *StockManager) FindByStockCode(stockCode string) ([]entity.StockEntity, error) {
// 	if stockCode == "" {
// 		return sm.FindAll()
// 	} else {
// 		if len(stockCode) >= 3 {
// 			return sm.FindWhere(fmt.Sprintf("code like '%%s%'", stockCode), 0, 0)
// 		}
// 		return make([]entity.StockEntity, 0), nil
// 	}
// }

// FindAllForMap 把所有股票信息转换成map，key 为股票代码，value 为股票信息
func (sm *StockManager) FindAllForMap() map[string]entity.StockEntity {
	entities, err := sm.FindAll()
	if err != nil {
		return nil
	}
	return slice.KeyBy(entities, func(item entity.StockEntity) string {
		return item.Code
	})
}
